# python中对于各种资源安全关闭提供了with语句，而with语句的背后是python的上下文管理协议（context manager protocol）

# 在不实用with之前需要手动调用close安全的进行关闭
file = open("with_test")
file_contents = file.read()
print(file_contents)

file.close()

# 使用了with关键字之后，不需要再手动的去开启和关闭资源了。
# 文件关闭
with open("with_test") as file:
    file_contents = file.read()
    print(file_contents)

# 上下文管理协议（context manager protocol）
# with语句背后是Python的上下文管理协议（Context Management Protocol）
# 它依赖于对象的__enter__和__exit__魔术方法。任何实现了这两个方法的对象都可以用作with语句的上下文管理器。

print("-" * 40)


# 自定义上下文管理器

class MyContextManager:
    def __enter__(self):
        print("进入上下文。。")
        return "hello,world!"

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("离开上下文。。")
        if exc_type:
            print(f"捕获到异常！{exc_type}")
        # 防止异常向外传播
        return True


# 打印进入上下文。。
with MyContextManager() as value:
    print(value)
# 离开上下文。。

# 打印进入上下文。。
with MyContextManager() as value:
    raise ValueError("参数错误！")
# 捕获到异常！<class 'ValueError'>